<?php /** @noinspection PhpDocMissingThrowsInspection */

/** @noinspection PhpUnhandledExceptionInspection */

namespace DreamCat\FrameCore\Cases\Dispatchers;

use DreamCat\FrameCore\Factory\Impl\Container\DefaultContainerFactory;
use DreamCat\FrameCore\Factory\Impl\Dispatchers\DefaultDispatcherFactory;
use DreamCat\FrameInterface\ConfigReader;
use FastRoute\Dispatcher;
use PHPUnit\Framework\TestCase;

/**
 * 派发器测试
 * @author -
 */
class DispatcherTest extends TestCase
{
    /**
     * 测试默认的派发器
     * @param array $config 创建派发器的配置
     * @param array $testCases 测试用例
     * @return void
     * @dataProvider defaultDataProvider
     */
    public function testDefault(array $config, array $testCases)
    {
        $configReader = $this->getMockForAbstractClass(ConfigReader::class);
        $configReader->method("get")
            ->willReturnCallback(
                function (string $path, $defaultValue = null) use ($config) {
                    if ($path == "router") {
                        return $config;
                    } else {
                        return $defaultValue;
                    }
                }
            );
        $container = (new DefaultContainerFactory())->create($configReader);
        /** @var DefaultDispatcherFactory $factory */
        $factory = $container->get(DefaultDispatcherFactory::class);
        $dispatcher = $factory->create(Dispatcher::class, "");

        foreach ($testCases as $case) {
            $handle = $dispatcher->dispatch($case["method"], $case["uri"]);
            static::assertEquals($case["handle"], $handle, "method = {$case["method"]}, case = {$case["uri"]}");
        }
    }

    /**
     * testDefault的测试数据
     * @return array
     * @see testDefault
     */
    public function defaultDataProvider()
    {
        return [
            # 第一组数据，带prefix
            [
                [
                    "prefix" => "/api",
                    "uris" => [
                        "str" => "strhandle",
                        "/child" => [
                            "/ch1" => [
                                "method" => "POST",
                                "handle" => "ch1Handle",
                            ],
                            "/ch2" => "ch2Handle",
                        ],
                        "/uri3" => [
                            "method" => "GET",
                            "handle" => "uri3Handle",
                        ],
                        "/{PathVar}/uri4" => "uri4Handle",
                        "/uri5" => [
                            "method" => [
                                "GET",
                                "POST",
                            ],
                            "handle" => "uri4Handle",
                        ],
                    ],
                ],
                [
                    [
                        "method" => "GET",
                        "uri" => "/api/str",
                        "handle" => [
                            Dispatcher::FOUND,
                            "strhandle",
                            [],
                        ],
                    ],
                    [
                        "method" => "POST",
                        "uri" => "/api/child/ch1",
                        "handle" => [
                            Dispatcher::FOUND,
                            "ch1Handle",
                            [],
                        ],
                    ],
                    [
                        "method" => "GET",
                        "uri" => "/api/child/ch2",
                        "handle" => [
                            Dispatcher::FOUND,
                            "ch2Handle",
                            [],
                        ],
                    ],
                    [
                        "method" => "GET",
                        "uri" => "/api/uri3",
                        "handle" => [
                            Dispatcher::FOUND,
                            "uri3Handle",
                            [],
                        ],
                    ],
                    [
                        "method" => "POST",
                        "uri" => "/api/uri3",
                        "handle" => [
                            Dispatcher::METHOD_NOT_ALLOWED,
                            ["GET"],
                        ],
                    ],
                    [
                        "method" => "GET",
                        "uri" => "/api/pv/uri4",
                        "handle" => [
                            Dispatcher::FOUND,
                            "uri4Handle",
                            ["PathVar" => "pv"],
                        ],
                    ],
                    [
                        "method" => "GET",
                        "uri" => "/api/uri5",
                        "handle" => [
                            Dispatcher::FOUND,
                            "uri4Handle",
                            [],
                        ],
                    ],
                    [
                        "method" => "POST",
                        "uri" => "/api/uri5",
                        "handle" => [
                            Dispatcher::FOUND,
                            "uri4Handle",
                            [],
                        ],
                    ],
                ],
            ],
            # 第二组数据，不带prefix
            [
                [
                    "uris" => [
                        "str" => "strhandle",
                        "/child" => [
                            "/ch1" => [
                                "method" => "POST",
                                "handle" => "ch1Handle",
                            ],
                            "/ch2" => "ch2Handle",
                        ],
                        "/uri3" => [
                            "method" => "GET",
                            "handle" => "uri3Handle",
                        ],
                        "/{PathVar}/uri4" => "uri4Handle",
                        "/uri5" => [
                            "method" => [
                                "GET",
                                "POST",
                            ],
                            "handle" => "uri4Handle",
                        ],
                    ],
                ],
                [
                    [
                        "method" => "GET",
                        "uri" => "/str",
                        "handle" => [
                            Dispatcher::FOUND,
                            "strhandle",
                            [],
                        ],
                    ],
                    [
                        "method" => "POST",
                        "uri" => "/child/ch1",
                        "handle" => [
                            Dispatcher::FOUND,
                            "ch1Handle",
                            [],
                        ],
                    ],
                    [
                        "method" => "GET",
                        "uri" => "/child/ch2",
                        "handle" => [
                            Dispatcher::FOUND,
                            "ch2Handle",
                            [],
                        ],
                    ],
                    [
                        "method" => "GET",
                        "uri" => "/uri3",
                        "handle" => [
                            Dispatcher::FOUND,
                            "uri3Handle",
                            [],
                        ],
                    ],
                    [
                        "method" => "POST",
                        "uri" => "/uri3",
                        "handle" => [
                            Dispatcher::METHOD_NOT_ALLOWED,
                            ["GET"],
                        ],
                    ],
                    [
                        "method" => "GET",
                        "uri" => "/pv/uri4",
                        "handle" => [
                            Dispatcher::FOUND,
                            "uri4Handle",
                            ["PathVar" => "pv"],
                        ],
                    ],
                    [
                        "method" => "GET",
                        "uri" => "/uri5",
                        "handle" => [
                            Dispatcher::FOUND,
                            "uri4Handle",
                            [],
                        ],
                    ],
                    [
                        "method" => "POST",
                        "uri" => "/uri5",
                        "handle" => [
                            Dispatcher::FOUND,
                            "uri4Handle",
                            [],
                        ],
                    ],
                ],
            ],
            # 第三组数据，带无效prefix
            [
                [
                    "prefix" => "",
                    "uris" => ["str/" => "strhandle"],
                ],
                [
                    [
                        "method" => "GET",
                        "uri" => "/api/str",
                        "handle" => [Dispatcher::NOT_FOUND],
                    ],
                    [
                        "method" => "GET",
                        "uri" => "/str",
                        "handle" => [
                            Dispatcher::FOUND,
                            "strhandle",
                            [],
                        ],
                    ],
                ],
            ],
        ];
    }
}

# end of file
